﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using UniCT.LinkShareWpf.Interface;
using System.Collections;
using System.Reflection;
using System.ComponentModel;
using System.Runtime.Serialization;
using System.Collections.Specialized;

namespace UniCT.LinkShareWpf.Model 
{
    // La decorazione [DataContract]: si tratta di un oggetto che viene utilizzato all'interno del contratto
    // (definisce metodi e oggetti scambiati nella comunicazione). 
    // Questo perché potrebbero esserci dei campi che nella comunicazione non interessano:
    // in quel caso, se non si mette la decorazione DataMember essi non vengono presi in considerazione.  
    [DataContract]
    public class Filter
    {
        // DataMember indica le proprietà o i campi che vogliamo serializzare
        [DataMember]
        private string title;
        [DataMember]
        private string director;
        [DataMember]
        private EnumLanguage language;
        [DataMember]
        private string type;
        [DataMember]
        private string rating;
        [DataMember]
        private string episodeN;
        [DataMember]
        private string seasonN;
        
        public string Director
        {
            get { return director; }
            set { director = value; }
        }

        public string Title
        {
            get { return title; }
            set { title = value; }
        }

        public EnumLanguage Language
        {
            get { return language; }
            set { language = value; }
        }

        public string Type
        {
            get { return type; }
            set { type = value; }
        }

        public string Rating
        {
            get { return rating; }
            set { rating = value; }
        }

        public string EpisodeN
        {
            get { return episodeN; }
            set { episodeN = value; }
        }

        public string SeasonN
        {
            get { return seasonN; }
            set { seasonN = value; }
        }

        char[] separators = { ' ', ',' };

        public Filter()
        {
            Reset();
        }

        public void Reset()
        {
            title = string.Empty;
            director = string.Empty;
            language = EnumLanguage.Italiano;
            type = "allRButton";
            rating = "allRatRButton";
            episodeN = "All";
            seasonN = "All";
        }

        public ObservableCollection<Resource> FilterResources(ObservableCollection<Resource> myList)
        {
            ObservableCollection<Resource> filteredList = new ObservableCollection<Resource>();
            NameValueCollection filterList = new NameValueCollection();

            if (!String.IsNullOrEmpty(title))
                filterList.Add("Title", title);
            if (!String.IsNullOrEmpty(director))
                filterList.Add("Director", director);
 


            foreach (Resource res in myList)
            {
                bool check2 = false;
                // In base ai criteri di Director e Titolo
                
                # region ricercainbaseai2criteri
                foreach (string filter in filterList.Keys)
                {
                    // Filter: Contiene il nome del campo da filtrare
                    // Attribute: è il valore relativo al campo
                    // ottimizzazione filtro:
                    // Inquesto modo appena c'è anche un campo che non coincide esce e non controlla più il resto

                    string attribute = res.CInfo.GetType().GetProperty(filter).GetValue(res.CInfo, null).ToString();

                    string[] partsOfString = filterList[filter].ToString().ToUpper().Split(separators);

                    foreach (string partOfString in partsOfString)
                    {
                        if (!attribute.ToUpper().Contains(partOfString))
                        {
                            check2 = true;
                            break;
                        }
                    }
                    if (check2)
                        break;
                }
                # endregion

                bool check3 = false;
                if (!check2)

                    #region Filtro in base alla lingue e alla qualità

                    //aggiungo i controlli in cascata per i campi obbligatori del filtro
                    if (language.Equals(res.CInfo.Language))
                    {
                        #region ricercainbasealrating

                        if (rating.Equals("highRatRButton"))
                        {
                            if (res.Rating >= 0.8)
                                    check3 = true;
                        }
                        else if (rating.Equals("lowRatRButton"))
                        {
                            if (res.Rating < 0.8)
                                    check3 = true;
                        }
                        else
                            check3 = true;

                        #endregion

                    }
                    #endregion


                if (check3)
                {

                    #region Filtro in base alla tiplogia della Risorsa

                    // Tutte le risorse
                    if (type.Equals("allRButton"))
                        filteredList.Add(res);
                    // Solamente i film, aggiungiamo quindi solo le risorse
                    // che non hanno come CINFO una serieTV
                    else if (type.Equals("filmRButton"))
                    {
                        if (!(res.CInfo is ContentInfoTVS))
                            filteredList.Add(res);
                    }

                    // Se si cerca solamente SerieTv

                    else if (type.Equals("tvseriesRButton") && res.CInfo is ContentInfoTVS)
                        //Sono nel caso in cui sto cercando una serie TV
                    {
                        if (seasonN.Equals("All"))
                        {
                            if (episodeN.Equals("All"))
                                filteredList.Add(res);
                            else
                                if (episodeN.Equals((res.CInfo as ContentInfoTVS).EpisodNumber.ToString()))
                                    filteredList.Add(res);
                        }
                        else
                            if (seasonN.Equals((res.CInfo as ContentInfoTVS).SeasonNumber.ToString()))
                            {
                                if (episodeN.Equals("All"))
                                    filteredList.Add(res);
                                else
                                    if (episodeN.Equals((res.CInfo as ContentInfoTVS).EpisodNumber.ToString()))
                                        filteredList.Add(res);
                            }
                    }
                    #endregion
                }
                   
            }
             
            return filteredList;
        }
    }

}
